home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1994 March
/
Internet Info CD-ROM (Walnut Creek) (March 1994).iso
/
networking
/
ip
/
ka9q
/
alpha.arc
/
PC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-07-26
|
6KB
|
256 lines
/* OS- and machine-dependent stuff for IBM-PC running MS-DOS */
#include <stdio.h>
#include <sgtty.h>
#include "global.h"
#include "mbuf.h"
#include "internet.h"
#include "iface.h"
#include "cmdparse.h"
/* This flag is set by setirq() if IRQ 8-15 is used, indicating
* that the machine is a PC/AT with a second 8259 interrupt controller.
* If this flag is set, the interrupt return code in pcgen.asm will
* send an End of Interrupt command to the second 8259 as well as the
* first.
*/
char isat;
/* Interface list header */
struct interface *ifaces;
/* Aztec memory allocation control */
int _STKLOW = 0; /* Stack above heap */
int _STKSIZ = 16384/16; /* 16K stack -- overridden in grabcore */
int _HEAPSIZ = 4096/16; /* Isn't really used */
int _STKRED = 4096; /* Stack red zone in bytes -- this really matters */
char ttbuf[BUFSIZ];
/* Called at startup time to set up console I/O, memory heap */
ioinit()
{
struct sgttyb ttybuf;
unsigned grabcore();
/* Save these two file table entries for something more useful */
fclose(stdaux);
fclose(stdprt);
/* Interrupts use a special stack deep in data space.
* Calls to sbrk() (invoked by malloc when it needs more memory
* from the system) at interrupt time will fail because sbrk()
* will think that the stack has overwritten the heap. So
* grab all the memory we can now for the heap so that malloc
* won't have to call sbrk and alloc_mbuf() won't fail unnecessarily
* at interrupt time.
*/
grabcore();
setbuf(stdout,ttbuf);
/* Put display in raw mode. Note that this breaks tab expansion,
* so you need to run NANSI.SYS or equivalent.
*/
ioctl(1,TIOCGETP,&ttybuf);
ttybuf.sg_flags = RAW;
ioctl(1,TIOCSETP,&ttybuf);
}
/* Called just before exiting to restore console state */
iostop()
{
struct sgttyb ttybuf;
setbuf(stdout,NULLCHAR);
ioctl(1,TIOCGETP,&ttybuf);
ttybuf.sg_flags &= ~RAW;
ioctl(1,TIOCSETP,&ttybuf);
while(ifaces != NULLIF){
if(ifaces->stop != NULLFP)
(*ifaces->stop)(ifaces);
ifaces = ifaces->next;
}
}
/* Spawn subshell */
doshell(argc,argv)
{
char *command,*getenv();
struct sgttyb ttybuf,ttysav;
int ret;
ioctl(1,TIOCGETP,&ttysav);
ioctl(1,TIOCGETP,&ttybuf);
ttybuf.sg_flags &= ~RAW;
ioctl(1,TIOCSETP,&ttybuf);
if((command = getenv("COMSPEC")) == NULLCHAR)
command = "/COMMAND.COM";
ret = fexecl(command,command,NULLCHAR);
ioctl(1,TIOCSETP,&ttysav);
if(ret == -1)
return -1;
else
return wait();
}
/* checks the time then ticks and updates ISS */
static short clockstart = 0;
static short clkval = 0;
void
check_time()
{
int32 iss();
short ntime;
if(!clockstart){
/* Executed only once */
clkval = peekw(0x6c,0x40);
clockstart = 1;
return;
}
/* Read the low order word of the BIOS tick counter directly. The
* INT 1Ah call isn't used because it stupidly clears the
* "midnight passed" flag and we'd have to update the date ourselves.
* (See Norton, p222).
*
* The PC's time-of-day handling is a real crock of shit. Why not a
* nice simple long binary count from a fixed UTC epoch, as in UNIX??
*/
ntime = peekw(0x6c,0x40);
while(ntime != clkval){ /* Handle possibility of several missed ticks */
clkval++;
icmpclk(); /* Call this one before tick */
tick();
(void)iss();
}
}
/* Read characters from the keyboard, translating them to "real" ASCII
* If none are ready, return the -1 from kbraw()
*/
int
kbread()
{
int kbraw(),c;
if((c = kbraw()) == 0){
/* Lead-in to a special char */
c = kbread();
switch(c){
case 3: /* NULL (bizzare!) */
c = 0;
break;
case 68: /* F-10 key (used as command-mode escape) */
c = -2;
break;
case 83: /* DEL key */
c = 0x7f;
break;
default: /* Dunno what it is */
c = -1;
}
}
return c;
}
#define CTLZ 26
/* Special version of aputc() (used by putchar and printf) that filters
* out nasty characters that screw up the DDOS and ANSI terminal drivers
*/
aputc(c,file)
char c;
FILE *file;
{
/* Nulls get displayed as spaces by ansi.sys (wrong)
* ^Z's seem to hang the DoubleDos and DesqView screen drivers
*/
if((c == '\0' || c == CTLZ) && file == stdout)
return c;
/* Do end-of-line translations */
if(c == '\n')
putc('\r',file);
return putc(c,file);
}
/* Reset the CPU, reboot DOS */
sysreset()
{
int16 regs[8]; /* Not really needed */
farcall(0x0,0xffff,regs,regs);
}
/* Install hardware interrupt handler.
* Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
* Note that bus line IRQ2 maps to IRQ9 on the AT
*/
setirq(irq,handler)
unsigned irq;
void (*handler)();
{
/* Set interrupt vector */
if(irq < 8){
setvect(8+irq,handler);
} else if(irq < 16){
isat = 1;
setvect(0x70 + irq - 8,handler);
} else {
return -1;
}
return 0;
}
/* Return pointer to hardware interrupt handler.
* Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
*/
void
(*getirq(irq))()
unsigned int irq;
{
void (*getvect())();
/* Set interrupt vector */
if(irq < 8){
return getvect(8+irq);
} else if(irq < 16){
return getvect(0x70 + irq - 8);
} else {
return NULLVFP;
}
}
/* Disable hardware interrupt */
maskoff(irq)
unsigned irq;
{
if(irq < 8){
setbit(0x21,(char)(1<<irq));
} else if(irq < 16){
irq -= 8;
setbit(0xa1,(char)(1<<irq));
} else {
return -1;
}
return 0;
}
/* Enable hardware interrupt */
maskon(irq)
unsigned irq;
{
if(irq < 8){
clrbit(0x21,(char)(1<<irq));
} else if(irq < 16){
irq -= 8;
clrbit(0xa1,(char)(1<<irq));
} else {
return -1;
}
return 0;
}
/* Return 1 if specified interrupt is enabled, 0 if not, -1 if invalid */
getmask(irq)
unsigned irq;
{
if(irq < 8)
return (inportb(0x21) & (1 << irq)) ? 0 : 1;
else if(irq < 16){
irq -= 8;
return (inportb(0xa1) & (1 << irq)) ? 0 : 1;
} else
return -1;
}